# ------------------------------
# 3. Pydantic模型 (数据验证和序列化)
# ------------------------------
from datetime import date
from enum import Enum
from typing import Literal, Annotated, Optional, List
from pydantic import BaseModel, Field, AfterValidator, ValidationInfo


# 定义学历枚举类型
class EducationLevel(str, Enum):
    大专 = "大专"
    本科 = "本科"
    硕士 = "硕士"
    博士 = "博士"

# 定义验证函数：确保毕业时间晚于入学时间
def check_graduation_date(v: date, info: ValidationInfo) -> date:
    enrollment_date = info.data.get('enrollment_date')
    if enrollment_date and v <= enrollment_date:
        raise ValueError("毕业时间必须晚于入学时间")
    return v



class StuSchema(BaseModel):
    """基础模型，包含所有学生信息的共有字段，用于数据验证"""

    stu_id: int = Field(..., gt=0, description="学生编号（正整数，唯一）")

    class_name: str = Field(..., min_length=1, max_length=20, description="学生班级")

    stu_name: str = Field(..., min_length=1, max_length=20, description="学生姓名")

    native_place: Optional[str] = Field(None, min_length=1, max_length=50, description="籍贯")

    graduate_school: Optional[str] = Field(None, min_length=1, max_length=100, description="毕业院校")

    major: Optional[str] = Field(None, min_length=1, max_length=50, description="专业")

    enrollment_date: Optional[date] = Field(None, description="入学时间")

    # 使用AfterValidator关联验证函数，简化代码
    graduation_date: Optional[Annotated[
        date,
        Field(description="毕业时间"),
        AfterValidator(check_graduation_date)
    ]] = None

    # 学历：大专/本科/硕士/博士
    education: Optional[EducationLevel] = Field(None, description="学历")

    advisor_id: Optional[int] = Field(None, gt=0, description="顾问编号（正整数）")

    age: Optional[int] = Field(None, ge=1, le=100, description="年龄")

    gender: Optional[Literal["男", "女"]] = Field(None, description="性别")

class StuCreateSchema(StuSchema):
    """创建学生模型：主键stu_id必填"""
    pass

class StuUpdateSchema(BaseModel):
    """修改学生模型：仅包含可修改的字段（stu_id通常不允许修改，单独排除）"""
    class_name: Optional[str] = Field(None, min_length=1, max_length=20, description="学生班级")

    stu_name: Optional[str] = Field(None, min_length=1, max_length=20, description="学生姓名")

    native_place: Optional[str] = Field(None, min_length=1, max_length=50, description="籍贯")

    graduate_school: Optional[str] = Field(None, min_length=1, max_length=100, description="毕业院校")

    major: Optional[str] = Field(None, min_length=1, max_length=50, description="专业")

    enrollment_date: Optional[date] = Field(None, description="入学时间")

    # 使用AfterValidator关联验证函数，简化代码
    graduation_date: Optional[Annotated[
        date,
        Field(description="入学时间"),
        AfterValidator(check_graduation_date)
    ]] = None

    # 学历：大专/本科/硕士/博士
    education: Optional[EducationLevel] = Field(None, description="学历")

    advisor_id: Optional[int] = Field(None, gt=0, description="顾问编号（正整数）")

    age: Optional[int] = Field(None, ge=1, le=100, description="年龄")

    gender: Optional[Literal["男", "女"]] = Field(None, description="性别")

class StuResponseSchema(StuSchema):
    """学生响应模型：包含关联的成绩和就业信息"""

    class Config:
        from_attributes = True  # 支持从ORM模型转换
